package com.humanminoritygame.model;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class HibernateSubscriptionRepo extends HibernateGenericRepo implements SubscriptionRepo {

	@Autowired
	public HibernateSubscriptionRepo(SessionFactory sessionFactory) {
		setSessionFactory(sessionFactory);
	}

	@Override
	public void addSubscription(Subscription subscription) {
	  Session session = getSession();
	  session.save(subscription);
		session.flush();
	}

	@SuppressWarnings("unchecked")
  @Override
	public Set<Subscription> getAllSubscriptions() {
	  Set<Subscription> subscriptions = new HashSet<Subscription>();
    subscriptions.addAll(getSession().createQuery("SELECT s FROM Subscription  s").list());
    return subscriptions;
	}

	@SuppressWarnings("unchecked")
  @Override
	public Set<Subscription> getRoomActiveSubscriptions(Room room) {
	  Set<Subscription> subscriptions = new HashSet<Subscription>();
	  Query q = getSession().createQuery("SELECT s FROM Subscription s WHERE room=:id AND state = 'ACTIVE'");
    q.setEntity("id",room);
    subscriptions.addAll(q.list());
    return subscriptions;
	}

	@SuppressWarnings("unchecked")
  @Override
	public Set<Subscription> getRoomSubscriptions(Room room) {
	  Set<Subscription> subscriptions = new HashSet<Subscription>();
	  Query q = getSession().createQuery("SELECT s FROM Subscription s WHERE room=:id");
    q.setEntity("id",room);
    subscriptions.addAll(q.list());
    return subscriptions;
	}

  @Override
	public Subscription getSubscription(User user, Category category) {
	//  Set<Subscription> subscriptions = new HashSet<Subscription>();
	  
	  Query q = getSession().createQuery("SELECT s FROM Subscription s , Room r" +
	  		" WHERE s.room = r.id AND s.user=:userid AND r.category=:categoryid AND r.state = 'OPEN' ");
    q.setEntity("userid",user);
    q.setEntity("categoryid",category);
    return (Subscription) q.uniqueResult();
    //TODO: en realidad un usuario y una categoria tienen mas de una subscripcion
    //porque van quedando las subscripciones de las rooms que se cerraron.
    //hay que hacer un metodo que te de la subcripcion activa de un user y un category
	}

	@Override
	public Subscription getSubscription(Long subscriptionId) {
		return (Subscription)getSession().get(Subscription.class, subscriptionId);
	}

	@SuppressWarnings("unchecked")
  @Override
	public Set<Subscription> getSubscriptions(Category category) {
	  Set<Subscription> subscriptions = new HashSet<Subscription>();
	  Query q = getSession().createQuery("SELECT s FROM Subscription  s WHERE category=:categoryid");
    q.setEntity("categoryid",category);
    subscriptions.addAll(q.list());
    return subscriptions;
	}

	@SuppressWarnings("unchecked")
  @Override
	public Set<Subscription> getUserSubscriptions(User user) {
		Set<Subscription> result = new HashSet<Subscription>();
		Query q = getSession().createQuery("SELECT s FROM Subscription s WHERE s.user=:user");
    q.setEntity("user",user);
		result.addAll(q.list());
		return result;
	}

	@SuppressWarnings("unchecked")
  @Override
	public boolean isSubscribed(User user, Category category) {
		// TODO REVISAAAAAARRR
	  // esto tendria que ser algo asi como si esta subscripto a un room activo
	  // porque si estan cerrados todos los rooms de ese category para ese usuario, 
	  //deberia retornar false
	  Set<Subscription> result = new HashSet<Subscription>();
	  Query q = getSession().createQuery("SELECT s FROM Subscription s, Room r, Category c WHERE s.user=:user AND s.room = r.id AND r.category = c.id AND c.id=:cid AND r.state <> 'CLOSED'");
    q.setEntity("user",user);
    q.setEntity("cid",category);
    result.addAll(q.list());
		return !result.isEmpty();
	}

	@SuppressWarnings("unchecked")
  @Override
  public Set<Subscription> getActiveSubscriptions(User user) {
    Set<Subscription> result = new HashSet<Subscription>();
    Query q = getSession().createQuery("SELECT s FROM Subscription s WHERE s.user=:user AND s.state= 'ACTIVE' ");
    q.setEntity("user",user);
    result.addAll(q.list());
    return result;
  }

	@SuppressWarnings("unchecked")
  @Override
  public Set<Subscription> getOpenSubscriptions(User user) {
    Set<Subscription> result = new HashSet<Subscription>();
    Query q = getSession().createQuery("SELECT s FROM Subscription s , Room r WHERE s.room=r AND  s.user=:user AND r.state= 'OPEN' ");
    q.setEntity("user",user);
    result.addAll(q.list());
    return result;
  }

  @Override
  public Subscription getSubscription(User user, Room room) {
    Query q = getSession().createQuery("SELECT s FROM Subscription s " +
        " WHERE s.user=:userid AND s.room=:room");
    q.setEntity("userid",user);
    q.setEntity("room",room);
    return (Subscription) q.uniqueResult();
  }

  @SuppressWarnings("unchecked")
  @Override
  public Set<Subscription> getClosedSubscriptions(User user) {
    Set<Subscription> result = new HashSet<Subscription>();
    Query q = getSession().createQuery("SELECT s FROM Subscription s , Room r WHERE s.room=r AND  s.user=:user AND r.state= 'CLOSED' ");
    q.setEntity("user",user);
    result.addAll(q.list());
    return result;
  }
  
  
  @SuppressWarnings("unchecked")
  @Override
  public ArrayList<Subscription> getRoomSubscriptionsOrderByScore(Room room){
    ArrayList<Subscription> result = new ArrayList<Subscription>();
    Query q = getSession().createQuery("SELECT s FROM Subscription s WHERE s.room=:room ORDER BY s.score DESC");
    q.setEntity("room", room);
    result.addAll(q.list());
    return result;
  }
  
  
  
}
